<script setup lang="ts">
import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css'; // 引入样式
import { ref, computed } from 'vue'
import type { PublishDataType } from '@/types/publish'
import { http } from '@/utils/myRequest'
import type { ElUpload, UploadFile, UploadRequestOptions } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import { getArticleDetailApi, publishApi } from '@/apis/publish'
import router from '@/router';
import { onBeforeRouteUpdate, useRoute, type RouteLocationNormalized } from 'vue-router';
import Quill from 'quill'


// 参数
const queryDraft = ref<boolean>(false)
const dataPublish = ref<PublishDataType>({
  title: '',
  content: '',
  cover: {
    type: 1,
    images: []
  },
  channel_id: null
})

// 上传图片
const uploadAction = async (fillObj: UploadRequestOptions) => {
  // 获取图片
  const fd = new FormData()
  fd.append('image', fillObj.file)
  const res = await http<{ url: string }>({url: '/v1_0/upload', data: fd, method: 'POST'})
  // 添加图片地址
  dataPublish.value.cover.images.push(res.data.data.url)
  // 校验封面类型
  publishForm.value?.validateField('cover')
  return res.data.data.url
}
// 封面类型切换回调函数
const upload = ref<InstanceType<typeof ElUpload> | null>(null) // 上传组件实例
const addImgType = () => {
  dataPublish.value.cover.images = [] // 清空参数中的图片
  upload.value?.clearFiles() // 清空上传图片
  // 校验封面类型
  publishForm.value?.validateField('cover')
}
//删除图片
const removeImg = (file: UploadFile) => {
  dataPublish.value.cover.images = dataPublish.value.cover.images.filter(item => item !== file.response)
  publishForm.value?.validateField('cover')
}
// 图片绑定
const fileListImg = computed(() => {
  return dataPublish.value.cover.images.map(item => ({ name: item, url: item, response: item }))
})

// 定义富文本工具栏选项
const toolbarOptions = [
  ['bold', 'italic', 'underline', 'strike'],        // 加粗 斜体 下划线 删除线
  ['blockquote', 'code-block'],                     // 引用 代码块
  [{ 'header': 1 }, { 'header': 2 }],               // 标题，键值对的形式；1、2表示字体大小更替
  [{ 'list': 'ordered' }, { 'list': 'bullet' }],    // 有序、无序列表
  [{ 'script': 'sub' }, { 'script': 'super' }],     // 上标/下标
  [{ 'indent': '-1' }, { 'indent': '+1' }],         // 缩进
  [{ 'direction': 'rtl' }],                         // 文本方向
  [{ 'size': ['small', false, 'large', 'huge'] }],  // 字体大小
  [{ 'header': [1, 2, 3, 4, 5, 6, false] }],        // 标题
  [{ 'color': [] }, { 'background': [] }],          // 字体颜色、背景颜色
  [{ 'font': [] }],                                 // 字体
  [{ 'align': [] }],                                // 对齐方式
  ['clean'],                                        // 清除文本格式
  ['link', 'image', 'video']                        // 链接、图片、视频
]

// 校验规则 --------------------
const publishForm = ref<InstanceType<typeof ElForm> | null>(null)
// 自定义校验图片
const imgValidator = (rule: null, value: PublishDataType['cover'], callback: (error?: Error) => void) => {
  // console.log(value)
  if (value.type === 1) {
    if (value.images.length !== 1) {
      return callback(new Error('上传一张图片啊！混蛋'))
    }
  } else if (value.type === 3) {
    if (value.images.length !== 3) {
      return callback(new Error('上传三张图片啊！混蛋'))
    }
  }
  callback()
}
const articleRules = { // 校验规则
  title: [
    { required: true, message: '请输入文章标题', trigger: 'blur' },
    { min: 5, max: 25, message: '文章标题5-25ge字符', trigger: 'blur' }
  ],
  cover: [
    // 自定义
    { validator: imgValidator, trigger: 'change' }
  ],
  channel_id: [
    { required: true, message: '请选择文章频道', trigger: 'change' }
  ],
  content: [
    { required: true, message: '请输入文章内容', trigger: 'input' }
  ]
}

// 发布gogogo
const publishGoGoGo = (flag: boolean) => {
  // 表单验证
  publishForm.value?.validate(async (valid: boolean) => {
    // 表单验证失败
    if (!valid) {
      ElMessage({ message: '请填写完整', type: 'error' });
      return
    }
    // 验证成功
    queryDraft.value = flag // 草稿?
    await publishApi(dataPublish.value, queryDraft.value)
    router.push('/article')
    ElMessage({
      message: queryDraft.value ? '保存草稿成功' : '发布文章成功',
      type: 'success'
    })
  })
}

// 获取文章详情 ------------------------------- 编辑
// 获取文章id
const route = useRoute()
const itemId = route.params.id
const getArticleDetail = async () => {
  try {
    const res = await getArticleDetailApi(itemId  as string)
    const { title, content, cover, channel_id } = res.data.data
    // 回显数据
    dataPublish.value = {
      title,
      content,
      cover,
      channel_id
    }
  } catch (e) {
    console.log(e)
    // 文章路径不对
    router.push('/article')
    ElMessage({
      message: '文章已经不存在了',
      type: 'error'
    })
  }
}
if (itemId) {
  getArticleDetail()
}

// 在VUE3中，Quill编辑器修改绑定数据为空''是，并不会更新本身的内容  解决办法------手动更新Quill编辑器内容为空--------
const quillEditor = ref<InstanceType<typeof QuillEditor> | null>(null) // 获取编辑器实例
let quillInstance: Quill | null = null
onMounted(() => {
  if (quillEditor.value) {
    quillInstance = quillEditor.value.getQuill() // 确保获取编辑器实例
  }
})

const clearContent = async () => { // 清空编辑器内容
  await nextTick() // 等待dom渲染完毕
  if (quillInstance) {
    quillInstance.setText('') // 手动清空Quill编辑器内容
  }
}

// update更新路由并且组件被复用 --- 重新请求新的文章 || 清空表单
onBeforeRouteUpdate((to:RouteLocationNormalized, from: RouteLocationNormalized, next: () => void) => {
  if (to.params.id && from.name === 'Publish') {
    getArticleDetail()
  } else {
    publishForm.value?.resetFields()
    clearContent()
  }
  next()
})

// 修复富文本清空校验不出来的bug
watch(() => dataPublish.value.content, (newValue) => {
  console.log(newValue)
  if (newValue === '<p><br></p>') {
    console.log('清空了')
    clearContent()
    dataPublish.value.content = ''
    publishForm.value?.validateField('content')
  }
  publishForm.value?.validateField('content')
})

</script>

<template>
  <div class="publish">
    <el-card shadow="always" :body-style="{ padding: '20px' }">
      <!-- 头部 -->
      <template v-slot:header>
        <div>
          <el-breadcrumb separator-class="el-icon-arrow-right">
            <el-breadcrumb-item to="/overview">首页</el-breadcrumb-item>
            <template v-if="itemId">
              <el-breadcrumb-item to="/article">内容管理</el-breadcrumb-item>
              <el-breadcrumb-item>编辑文章</el-breadcrumb-item>
            </template>
            <el-breadcrumb-item v-else>发布文章</el-breadcrumb-item>
          </el-breadcrumb>
        </div>
      </template>
      <!-- 表单 -->
      <el-form ref="publishForm" :model="dataPublish" :rules="articleRules" label-width="120px">
        <!-- 标题 -->
        <el-form-item label="标题：" prop="title">
          <el-input v-model="dataPublish.title" placeholder="请输入文章标题" style="width: 400px; height: 40px;"></el-input>
        </el-form-item>
        <!-- 频道 -->
        <el-form-item label="频道：" prop="channel_id">
          <JkSelect :width="400" v-model="dataPublish.channel_id"></JkSelect>
        </el-form-item>
        <!-- 封面类型 -->
        <el-form-item label="封面：" prop="cover">
          <el-radio-group v-model="dataPublish.cover.type" @change="addImgType">
            <el-radio :value="1">单图</el-radio>
            <el-radio :value="3">仨图</el-radio>
            <el-radio :value="0">无图</el-radio>
            <el-radio :value="-1">自动</el-radio>
          </el-radio-group>
        </el-form-item>
          <!-- 封面图片 -->
        <el-form-item label="">
          <div v-if="dataPublish.cover.type !== 0 && dataPublish.cover.type !== -1">         
            <el-upload
              ref="upload"
              action=""
              list-type="picture-card"
              :http-request="uploadAction"
              :limit="dataPublish.cover.type"
              :on-remove="removeImg"
              :file-list="fileListImg"
            >
              <el-icon><Plus /></el-icon>
            </el-upload>
          </div>
        </el-form-item>
        <!-- 内容 -->
        <el-form-item label="内容：" prop="content">
          <div>
            <QuillEditor
              ref = "quillEditor"
              v-model:content="dataPublish.content"
              contentType="html"
              :toolbar="toolbarOptions"
              theme="snow"
              placeholder="请输入内容..."
            ></QuillEditor>
          </div>
        </el-form-item>
        <!-- 按钮 -->
        <el-form-item label="">
          <el-button type="primary" @click="publishGoGoGo(false)">发布文章</el-button>
          <el-button @click="publishGoGoGo(true)">存为草稿</el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<style scoped>
  :deep(.ql-editor) {
    width: 100%;
    min-height: 300px !important;
  }
  :deep(.el-upload-list__item)  {
    transition: none;
  }
</style>
